package com.simpleplayer.views.videoview;

import android.annotation.SuppressLint;
import android.content.Context;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewParent;
import android.widget.ImageView;
import android.widget.SeekBar;
import android.widget.TextView;

import com.simpleplayer.R;
import com.simpleplayer.MediaPlayer.SimplePlayer;
import com.simpleplayer.services.LogUtil;
import com.simpleplayer.services.TimeUtil;
import com.simpleplayer.views.customview.CustomTextView;

@SuppressLint("ViewConstructor")
class FullScreenVideoView extends VideoViewInternal {
    private final static String TAG = "FullScreenVideoView";

    private static final int HIDE_CONTROLS_DELAY = 4000; // 单位: 毫秒
    private static final int MAX_SEEK_BAR_PROGRESS = 100;
    private static final int SEEK_BAR_INCREMENT = 1; // 进度条增量

    // 显示控件
    private ViewGroup mFullscreenContainer;
    private ViewGroup mControlsContainer;       // 容纳播放控件的容器
    private ViewGroup mContentContainer;        // 容纳视频的容器
    private ImageView mPlayButton;              // 播放/暂停按钮
    private ImageView mEnterFloatWindowButton;  // 进入小窗按钮
    private ImageView mEnterInlineButton;       // 进入全屏按钮
    private ImageView mReturnButton;            // 返回(小屏)按钮
    private TextView mPositionView;
    private TextView mDurationView;
    private SeekBar mSeekBar;
    private CustomTextView mInfosView;

    private final Context mContext;
    private final VideoView mParent;
    private final SimplePlayer mPlayer;
    private Runnable mHideControlsTask;
    private boolean mDragSeekBar;

    public FullScreenVideoView(Context context, SimplePlayer player, VideoView parent) {
        super(context);
        LogUtil.d(TAG, "create a FullScreenVideoView " + this);
        mContext = context;
        mParent = parent;
        mPlayer = player;

        initViews();
        initCommon();
    }

    @SuppressLint("ClickableViewAccessibility")
    private void initViews() {
        View.inflate(mContext, R.layout.fullscreen_video_view, this);

        mFullscreenContainer = findViewById(R.id.fullscreen_container);
        mControlsContainer = findViewById(R.id.fullscreen_controls_container);
        mContentContainer = findViewById(R.id.fullscreen_content_container);
        mPlayButton = findViewById(R.id.fullscreen_play_button);
        mEnterFloatWindowButton = findViewById(R.id.fullscreen_float_button);
        mEnterInlineButton = findViewById(R.id.fullscreen_inline_button);
        mReturnButton = findViewById(R.id.fullscreen_return_button);
        mInfosView = findViewById(R.id.fullscreen_infos);
        mPositionView = findViewById(R.id.fullscreen_position);
        mDurationView = findViewById(R.id.fullscreen_duration);
        mSeekBar = findViewById(R.id.fullscreen_progress_bar);

        OnControlsClickListener clickControlsListener = new OnControlsClickListener();
        mReturnButton.setOnClickListener(clickControlsListener);
        mPlayButton.setOnClickListener(clickControlsListener);
        mEnterInlineButton.setOnClickListener(clickControlsListener);
        mEnterFloatWindowButton.setOnClickListener(clickControlsListener);
        mFullscreenContainer.setOnClickListener(new OnFullscreenViewsClickListener());
        mSeekBar.setOnSeekBarChangeListener(new CustomSeekBarChangeListener());
        mSeekBar.setOnTouchListener(new OnFullscreenViewsTouchListener());
        mSeekBar.setMax(MAX_SEEK_BAR_PROGRESS);
        mSeekBar.setKeyProgressIncrement(SEEK_BAR_INCREMENT);
    }

    private void initCommon() {
        setLayoutParams(
            new ViewGroup.LayoutParams(
                ViewGroup.LayoutParams.MATCH_PARENT,
                ViewGroup.LayoutParams.MATCH_PARENT
            )
        );

        mPlayer.addListener(new SimplePlayerListener());
    }

    @Override
    public void setContentView(View contentView) {
        if (contentView == null) return;
        // 将view从其父容器移除
        ViewParent parent = contentView.getParent();
        if (parent instanceof ViewGroup) {
            ((ViewGroup)parent).removeView(contentView);
        }

        // 替换展示的view
        if (mContentContainer.getChildCount() != 0) {
            mContentContainer.removeAllViews();
        }
        mContentContainer.addView(contentView);

        LogUtil.d(TAG, "setContentView " + contentView);
    }

    // ---------------------------------------------------------------------------------------------
    // 控件显示/隐藏
    private void showControlsOnce() {
        // 显示全屏控件，5s后自动消失
        LogUtil.i(TAG, "showControlsOnce " + this);
        mControlsContainer.setVisibility(VISIBLE);
        hideControlsDelay();
    }

    private void showControls() {
        // 永久显示全屏控件
        LogUtil.i(TAG, "showControls " + this);
        mControlsContainer.setVisibility(VISIBLE);
        if (mHideControlsTask != null) {
            getHandler().removeCallbacks(mHideControlsTask);
        }
    }

    private void hideControls() {
        LogUtil.i(TAG, "hideControls " + this);
        mControlsContainer.setVisibility(INVISIBLE);
    }

    private void hideControlsDelay() {
        // 延迟delayMillis(ms)后隐藏控件
        if (mHideControlsTask == null) {
            mHideControlsTask = this::hideControls;
        }
        getHandler().removeCallbacks(mHideControlsTask);
        getHandler().postDelayed(mHideControlsTask, HIDE_CONTROLS_DELAY);
    }
    // ---------------------------------------------------------------------------------------------

    // ---------------------------------------------------------------------------------------------
    // Listener 定义
    private class OnControlsClickListener implements View.OnClickListener {
        @Override
        public void onClick(View v) {
            if (mEnterFloatWindowButton.equals(v)) {
                // 进入小窗
                mParent.switchDisplayModeTo(VideoView.FLOATWINDOW);
            } else if (mEnterInlineButton.equals(v) || mReturnButton.equals(v)) {
                // 进入小屏
                mParent.switchDisplayModeTo(VideoView.INLINE);
            } else if (mPlayButton.equals(v)) {
                // 播放/暂停
                mPlayer.toggle();
                showControlsOnce();
            }
        }
    }

    private class OnFullscreenViewsClickListener implements View.OnClickListener {
        @Override
        public void onClick(View v) {
            // 单击小屏，显示控件
            showControlsOnce();
        }
    }

    private class OnFullscreenViewsTouchListener implements View.OnTouchListener {
        @SuppressLint("ClickableViewAccessibility")
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            if (event.getAction() == MotionEvent.ACTION_DOWN) {
                // 开始按压，显示控件
                showControls();
            } else if (event.getAction() == MotionEvent.ACTION_UP) {
                // 按压结束，隐藏控件
                hideControlsDelay();
            }
            return false;
        }
    }

    private class CustomSeekBarChangeListener implements SeekBar.OnSeekBarChangeListener {

        @Override
        public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
            // do nothing
        }

        @Override
        public void onStartTrackingTouch(SeekBar seekBar) {
            // 开始拖动进度条
            LogUtil.i(TAG, "Seekbar StartTrackingTouch");
            mDragSeekBar = true;
        }

        @Override
        public void onStopTrackingTouch(SeekBar seekBar) {
            LogUtil.i(TAG, "Seekbar StopTrackingTouch");
            mDragSeekBar = false;
            mPlayer.seekTo(mSeekBar.getProgress() * mPlayer.getDuration() / mSeekBar.getMax());
        }
    }

    private class SimplePlayerListener implements SimplePlayer.Listener {
        @SuppressLint({"SetTextI18n", "SwitchIntDef"})
        @Override
        public void onStateChanged(int oldState, int newState) {
            switch (newState) {
                case SimplePlayer.PREPARING:
                    mInfosView.setTextAndShow(R.string.video_preparing_info);
                    break;
                case SimplePlayer.PREPARED:
                    mSeekBar.setMax((int)(mPlayer.getDuration()));
                    mDurationView.setText(TimeUtil.secToTime(mPlayer.getDuration() / 1000));
                    mInfosView.setTextAndShow(R.string.video_onprepared_info);
                    break;
                case SimplePlayer.PLAYING:
                    mInfosView.clearAndHide();
                    mPlayButton.setBackgroundResource(R.drawable.ic_pause);
                    setKeepScreenOn(true);
                    break;
                case SimplePlayer.PAUSE:
                    mPlayButton.setBackgroundResource(R.drawable.ic_play);
                    setKeepScreenOn(false);
                    break;
                case SimplePlayer.STOP:
                    mPlayer.removeListener(FullScreenVideoView.SimplePlayerListener.this);
                    mPlayButton.setBackgroundResource(R.drawable.ic_play);
                    break;
                case SimplePlayer.ERROR:
                    mInfosView.setTextAndShow(R.string.video_error_info);
                    break;
                default:
                    break;
            }
        }

        @Override
        public void onTimeChanged(long timeMs) {
            if (!mDragSeekBar) {
                mSeekBar.setProgress((int)(timeMs * mSeekBar.getMax() / mPlayer.getDuration()));
                mPositionView.setText(TimeUtil.secToTime(timeMs / 1000));
            }
        }

        @Override
        public void onBufferingStart() {
            if (mPlayer.getCurrentDisPlayMode() != SimplePlayer.FULLSCREEN) return;
            mPlayer.stopCalculateBandwidth();
            mPlayer.startCalculateBandwidth(100, bandwidthEstimate ->
                    mInfosView.setTextAndShow("视频正在缓冲中: " + bandwidthEstimate + "kb/s"));
        }

        @Override
        public void onBufferingEnd() {
            if (mPlayer.getCurrentDisPlayMode() != SimplePlayer.FULLSCREEN) return;
            mPlayer.stopCalculateBandwidth();
            mInfosView.clearAndHide();
        }
    }
}
